package net.sxnic.workflow;

import java.lang.reflect.Constructor;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import net.sxnic.comm.attachment.Attachment;
import net.sxnic.comm.search.Search;
import net.sxnic.comm.search.SearchManager;
import net.sxnic.ugr.UgrActionSupport;
import net.sxnic.ugr.context.AppContext;
import net.sxnic.workflow.conf.WfConfigUtils;
import net.sxnic.workflow.context.WfContextImpl;
import net.sxnic.workflow.handler.HandlerExt;
import net.sxnic.workflow.invoker.WfHandlerInvoker;
import net.sxnic.workflow.node.utils.ButtonUtils;
import net.sxnic.workflow.pi.PiManager;
import net.sxnic.workflow.task.Task;
import net.sxnic.workflow.task.TaskManager;
import net.sxnic.workflow.wfentity.WfEntity;
import net.sxnic.workflow.wfentity.WfEntityManager;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 工作流action基础类
 * 
 * @author 孙宇飞
 * 
 */
@SuppressWarnings("serial")
public class WfActionSupport extends UgrActionSupport {

	private static Logger logger = LoggerFactory
			.getLogger(WfActionSupport.class);

	/**
	 * 系统风格 item项目申报风格
	 */
	public static String SYSTEM_CATE = "item";

	protected String taskId;

	protected String buttonType;

	protected WfContextImpl<WfEntity> context;

	@Autowired
	protected TaskManager taskManager;

	@Autowired
	protected WfEntityManager wfenManager;

	@Autowired
	protected SearchManager searchManager;

	@Autowired
	protected PiManager piManager;

	protected WfEntity wfentity;

	/**
	 * 从配置文件读取的指定转入页面
	 */
	protected String jsp;

	/**
	 * 自动生成页面需要的button的HTML
	 */
	protected String buttonHtml;

	/**
	 * 正文编辑标记代码
	 */
	protected String zwEditCode;

	/**
	 * 系统风格 kj 科技蓝 jw 纪委红
	 */
	protected String scate;

	public String getScate() {
		return SYSTEM_CATE;
	}

	protected void createButtonHtml() {
		buttonHtml = ButtonUtils.createButtonsHtml(context.getTask().getNode()
				.getButtons(), request.getContextPath());
	}

	/**
	 * 删除附件统一用次方法，要传的参数：deletedAttachmentId附件ID，和id实体Id
	 */
	protected void deleteAttachment() {
		String attachmentId = request.getParameter("deletedAttachmentId");
		if (StringUtils.isNotBlank(attachmentId)) {
			Set<Attachment> attachments = wfentity.getAttachments();
			for (Attachment a : attachments) {
				if (attachmentId.equals(a.getId())) {
					attachments.remove(a);
					break;
				}
			}
			wfentity.setAttachments(attachments);
			wfenManager.update(wfentity);// 验证通过 保存实体
			addLog("=====删除附件成功====:" + "附件个数" + attachments.size());
			context.setErrorMsg("附件删除成功!");
		}
	}

	/**
	 * action正式处理之前准备工作
	 */
	protected void before() {

		if (context == null) {
			context = new WfContextImpl<WfEntity>();
			logger.debug("context is null, rebuilding........");
		}

		if (StringUtils.isNotBlank(taskId)) {
			logger.debug("===taskId===" + taskId);
			context.setTaskId(taskId);
			context.setTask(taskManager.get(taskId));
			context.setTaskName(context.getTask().getName());
			context.setProcessName(context.getTask().getProcessName());
			context.setEntityId(context.getTask().getMdata().getId());
		}

		if (wfentity == null) {
			wfentity = wfenManager.get(context.getEntityId());
		} else {
			// wfentity = wfenManager.get(context.getEntityId());
		}

		context.setEntity(wfentity);
		context.setTaskManager(taskManager);
		context.setWfenManager(wfenManager);
	}

	/**
	 * 按指定操作，调用处理器
	 * 
	 * @param action
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected void invoke(String action) throws Exception {

		Set<HandlerExt> handlers = new LinkedHashSet<HandlerExt>();

		Set<String> handler_names = WfConfigUtils.findHandlers(
				context.getProcessName(), context.getTaskName(), action);

		// 从Handler Name 实例化为对象
		for (String handler_name : handler_names) {
			Class clazz = Class.forName(handler_name);
			Constructor c = clazz.getConstructor(WfContextImpl.class);
			HandlerExt hh = (HandlerExt) c.newInstance(context);
			handlers.add(hh);
		}

		WfHandlerInvoker<WfEntity> invoker = null;

		// 执行所有handler的edit方法
		for (HandlerExt h : handlers) {
			try {
				invoker = new WfHandlerInvoker<WfEntity>(h);
				if ("save".equals(action)) {
					invoker.save();
				} else if ("edit".equals(action)) {
					invoker.edit();
				} else if ("submit".equals(action)) {
					invoker.submit();
				} else {
					invoker.view();
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new Exception(e.toString());
			}
		}
	}

	/**
	 * 删除实体
	 */
	public void deleteEntity() throws Exception {

		// 删除任务
		List<Task> taskList = taskManager.findBy("entity", wfentity);
		for (Task t : taskList) {
			taskManager.delete(t);
		}

		wfenManager.delete(wfentity);

		addLog("delete-entityid+" + wfentity.getId() + "删除-成功:"
				+ wfentity.getTitle());
		msg = "deleteSuccess";
	}

	/**
	 * 退回操作
	 * 
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void sendBack() throws Exception {
		Set<HandlerExt> handlers = new LinkedHashSet<HandlerExt>();

		Set<String> handler_names = new LinkedHashSet<String>();
		handler_names.add("net.sxnic.workflow.whimpl.FindEntityHandler");
		handler_names.add("net.sxnic.workflow.whimpl.SignPwdValidateHandler");
		handler_names.add("net.sxnic.workflow.whimpl.SaveEntityHandler");
		handler_names.add("net.sxnic.workflow.whimpl.SendBackHandler");

		// 从Handler Name 实例化为对象
		for (String handler_name : handler_names) {
			Class clazz = Class.forName(handler_name);
			Constructor c = clazz.getConstructor(WfContextImpl.class);
			HandlerExt hh = (HandlerExt) c.newInstance(context);
			handlers.add(hh);
		}

		WfHandlerInvoker<WfEntity> invoker = null;

		for (HandlerExt h : handlers) {
			try {
				invoker = new WfHandlerInvoker<WfEntity>(h);
				invoker.submit();
			} catch (Exception e) {
				e.printStackTrace();
				logger.error(e.toString());
				return;
			}
		}
	}

	/**
	 * 把信息类的内容加入到全文检索列表中
	 */
	protected void addSearch() {

		Search s = null;

		s = searchManager.findByEntityIdBelonger(context.getEntityId(),
				AppContext.getUserName(request));

		if (s == null) {
			s = new Search();
		}

		s.setName(wfentity.getTitle());
		s.setModuleName(context.getTaskName());
		s.setEntityId(wfentity.getId());
		s.setSummary(wfentity.getKeyword());
		s.setBelonger(AppContext.getUserName(request));
		s.setUrl("/task/treat.jspa?taskId=" + taskId);

		searchManager.save(s);
	}

	public WfEntity getWfentity() {
		return wfentity;
	}

	public void setWfentity(WfEntity wfentity) {
		this.wfentity = wfentity;
	}

	public String getJsp() {
		return jsp;
	}

	public void setJsp(String jsp) {
		this.jsp = jsp;
	}

	public String getButtonType() {
		return buttonType;
	}

	public void setButtonType(String buttonType) {
		this.buttonType = buttonType;
	}

	public String getTaskId() {
		return taskId;
	}

	public void setTaskId(String taskId) {
		this.taskId = taskId;
	}

	public WfContextImpl<WfEntity> getContext() {
		return context;
	}

	public void setContext(WfContextImpl<WfEntity> context) {
		this.context = context;
	}

	public String getButtonHtml() {
		return buttonHtml;
	}

	public void setButtonHtml(String buttonHtml) {
		this.buttonHtml = buttonHtml;
	}

	public String getZwEditCode() {
		return zwEditCode;
	}

	public void setZwEditCode(String zwEditCode) {
		this.zwEditCode = zwEditCode;
	}

	public void setScate(String scate) {
		this.scate = scate;
	}
}